物件導向(OOP)是一種程式設計思維,其主豐是在更高層次上,將程序所涉及到的實體和實體之間的關係進行更好的管理及復用,減少程式開發的負擔。
OOP的三要素是封裝、繼承和多型。
封裝:隱藏物件的屬性和實現細節,僅對外公開介面,控制在程式中屬性的讀和修改的訪問級別。
封裝的目的是增強安全性和簡化程式設計,使用者不必瞭解具體的實現細節,只要通過外部介面使用已開發完成的方法。
繼承:通過繼承實現程式碼複用。繼承而得到的類稱為子類,被繼承的類稱為父類。子類不能繼承父類中訪問許可權為private的成員變數和方法。子類可以重寫父類的方法或重新命名與父類同名的成員變數。
多型:相同的函數呼叫介面,傳送不同的物件變數時,可以有不同的行為。多型又分為設計時多型和執行時多型。
在不同的程式語言裡有著不同的OOP實現方式。以Java為例,Java 支持 extends 也支持 interface ,extends 就是繼承, A extends B ,表明A是B的子類,A擁有B所有的公共屬性和方法。
Go語言並沒有像 C 或 Java 語言中的class類,它只有 C 語言的結構體,用結構體和指標等特性,完成一個類的功能。有些人在學習Go語言的class很不理解,其實C、Java等物件導向的語言中,class的底層實現就是結構體,物件的引用就是指標,Go語言只是少了class的語法糖而已。
此外,Go語言在設計之初就有感於繼承的使用在大型專案裡頭難以維護的問題,因些Go語言裡並沒有繼承,而是用內嵌(embeded)的方式去實現代碼的重複使用。
Go語言裡,每個包裡頭就是一個類,我們不需要class關鍵字宣告類。在其他語言裡中的類屬性和實例函數,Go以Struct和func實現。
舉例來說,若我們想要實作一個Rect類,它有兩個屬性叫作width和height,並且擁有有一個實例函數Area()會返回矩形的面積
type Rect struct{ //宣告一個Rect的結構體
width, height int //Rect有兩個屬性分別是widthheight
}
接著我們實作一個屬於Rect的Area函數,實例函數的宣告和一般函數類似,唯一不同的地方在於我們在func關鍵字和函數識別字之間要給定此函數綁定至哪個結構體。
func r Rect Area() int{
return r.width*height
}
在Go語言裡,並不像其他語言有private和public將類方法或是屬性宣告成公共或私有。Go是依賴首字器的大小寫來做為公眾或私有的依據。
大寫字母開頭為公共屬性/函數,可以從外部呼叫,小寫字母開頭為私有屬性/函數,只能內部使用。
type Rect struct{
width, height int //Rect.width和Rect.height為私有屬性
X,Y int //Rect.X和Rect.Y為公共屬性
}
func r Rect Area() int{
return r.width*height --> r.height
}